#include "../hardware/usart.h"
#include "stream.h"
#include "sys_timer.h"

void StreamInit(STREAM_SOURCE_E source, void * param) {
    switch (source) {
        case SOURCE_USART1:
        case SOURCE_USART2:
        case SOURCE_USART3:
        case SOURCE_USART4:
        case SOURCE_USART5:
            SOURCE_USART_PARAM_T *p = (SOURCE_USART_PARAM_T *)param;
            UsartInit(source, p->badurate, p->remap);
            break;
    }
}

STREAM_ERR_E StreamReadC(STREAM_SOURCE_E source, uint8_t * out) {
    STREAM_ERR_E ret = STREAM_FAIL;
    if (source <= SOURCE_USART5) {
        if (UsartGetC(source, out) == U_ERR_SUCCSE) {
            ret = STREAM_SUCCESS;
        }
    }
    return ret;
}

uint32_t StreamReads(STREAM_SOURCE_E source, uint8_t * out, uint32_t read_len, uint32_t outtime_ms) {
    uint32_t tmp_time = CurMillis();
    uint32_t len = 0;
    switch (source) {
        case SOURCE_USART1:
        case SOURCE_USART2:
        case SOURCE_USART3:
        case SOURCE_USART4:
        case SOURCE_USART5:
            uint8_t ch;
            while (read_len--) {
                while (UsartGetC(source, &ch) != U_ERR_SUCCSE) {
                    if (outtime_ms !=0 && ((outtime_ms + tmp_time) < CurMillis()))
                        return len;
                }
                *out = ch;
                out++;
                len++;
            }
            break;
    }
    return len;
}

STREAM_ERR_E StreamWriteC(STREAM_SOURCE_E source, uint8_t out) {
    STREAM_ERR_E ret = STREAM_FAIL;
    if (source <= SOURCE_USART5) {
        UsartPutC(source, out);
        ret = STREAM_SUCCESS;
    }
    return ret;
}

uint32_t StreamWrites(STREAM_SOURCE_E source, uint8_t * out, uint32_t len) {
    switch (source) {
        case SOURCE_USART1:
        case SOURCE_USART2:
        case SOURCE_USART3:
        case SOURCE_USART4:
        case SOURCE_USART5:
            UsartPuts(source, out, len);
            break;
    }
    return len;
}

void StreamTest(STREAM_SOURCE_E source, USART_REMAP_E remap) {
    uint8_t ch;
    SOURCE_USART_PARAM_T param = {115200, remap};
    uint32_t tmp_time = CurMillis();
    StreamInit(source, &param);
    while (1) {
        if (StreamReadC(source, &ch) == STREAM_SUCCESS) {
            StreamWriteC(source, ch);
        }
        if ((tmp_time + 500) < CurMillis()) {
            tmp_time = CurMillis();
            StreamWriteC(source, 0x12);
        }
    }
}
